package cn.xw.workQueuesAck;

import cn.xw.utils.ChannelUtil;
import com.rabbitmq.client.Channel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * @author AnHui OuYang
 * @version 1.0
 * created at 2023-04-12 0:09
 * 消费者A
 */
public class ConsumerA {

    //通过日志管理器获取Logger对象
    static Logger logger = LogManager.getLogger(Producer.class);
    //简单队列名称
    public static final String QUEUE_NAME = "WorkQueuesAckDemo";

    public static void main(String[] args) throws IOException {
        //调用自己的工具类获取信道
        Channel channel = ChannelUtil.getChannel();
        //创建队列 以防启动消费者发现队列不存在报错
        channel.queueDeclare(QUEUE_NAME, true, false, false, null);
        logger.info("消费者A开始监听队列消息....");
        //设置手动应答
        boolean autoAck = false;
        //消费者消费消息
        channel.basicConsume(QUEUE_NAME, autoAck, (consumerTag, message) -> {
            logger.info("A消费者已经接收到队列发送的ID为：{} 的消息", message.getEnvelope().getDeliveryTag());
            try {
                //这里我就一句打印语句，没有复杂逻辑，正常这里有复杂业务
                logger.info("A消费者获取队列信息正在处理：{}", new String(message.getBody(), StandardCharsets.UTF_8));
                int i = 1 / 0;
                //手动确认应答 不批量应答
                channel.basicAck(message.getEnvelope().getDeliveryTag(), false);
                logger.info("A消费者已经成功应答，ID为：{} 的消息", message.getEnvelope().getDeliveryTag());
            } catch (Exception e) {
                e.printStackTrace();
                //出现异常手动进行不应答;并且放入队列中(2种方式nack或者reject)
                channel.basicNack(message.getEnvelope().getDeliveryTag(), false, true);
                //channel.basicReject(message.getEnvelope().getDeliveryTag(), true);
                //channel.basicRecover(true);
                logger.info("A消费者未成功应答，消息处理失败，ID为：{} 的消息", message.getEnvelope().getDeliveryTag());
            }
        }, consumerTag -> {
            logger.info("监听的队列出现异常；可能队列被删除！{}", consumerTag);
        });
    }
}
